//========================================================//
// Socket Lib                                             //
// Basic classes ans interfaces                           //
// Author: Krechetov Anton aka kae   kae@gorodok.net      //
// NSU FIT May-July 2004                                  //
//========================================================//

#ifndef _MISC_SOCKETS_
#define _MISC_SOCKETS_
//#include "C:\\Documents and Settings\\sfaktorovich\\My Documents\\remoteconsole2\\vld.h"

#ifndef _WIN32
#include <arpa/inet.h>
#include <sys/ioctl.h>
#endif

#include "osocklib.h"
#include "../common/packet.h"
#include "sockstack.h"
#include <stdio.h>//need for "sprintf" function
#include <queue>

namespace BAM
{
	using namespace std;

	class cProxySocket : public cSocket
	{
	private:
		cIPAddr vProxyAddr;

	public:
		cProxySocket(const cIPAddr& proxyaddr);
		void connect(const cIPAddr& addr);
		iSocket* clone() const;
	};

	class cBackServerSocket : public iSelectable
	{
	private:
		iSocket* vTransport;
		Sock_State vState;

	public:
		cBackServerSocket(iSocket* transport = 0);
		~cBackServerSocket();
	    void listen(const cIPAddr &Addr);
	    void accept(cPSocket &C, bool waitinit);
	    Sock_State state() const;
		bool isReadable();
		bool isWriteable();
		bool isAcceptable();
		SOCKET descriptor();
	};

	const Sock_State DummyStart = 0;
	const Sock_State DummyNormal = 1;
	const Sock_State DummyEnd = 2;

	class cDummyController : public iPacketController
	{
	private:
		queue<cPacket> vIncomingQ;
		queue<cPacket> vOutcomingQ;
		Sock_State vState;

	public:
		cDummyController();

		void onConnect(const cIPAddr &Addr);
		void onDisconnect();
		void onInit(const cIPAddr &Addr);
		void onSend(const cPacket &P);
		void onRecv(const cPacket &P);

		bool haveOutcome() const;
		bool haveIncome() const;

		bool isInited() const;// returns true if is ready to send data?
		bool isFinished() const;// returns true if in an invalid state or if work is finished
		Sock_State state(Sock_State TransportState) const;
	   
		cPacket outcome();
		cPacket income();
		iPacketController* clone() const;
	};

	class cPipe
	{
	private:
		iSocket* vLeft;
		iSocket* vRight;

	public:
		cPipe();
		iSocket* getLeft();
		iSocket* getRight();
	};
}
#endif
